/*
 * JBoss, Home of Professional Open Source
 * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
 * contributors by the @authors tag. See the copyright.txt in the
 * distribution for a full listing of individual contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package za.ac.nmmu.muhelp.startup;

import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.inject.Inject;

//
// these imports are for XMPP
//
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Type;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.filter.IQTypeFilter;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;


import za.ac.nmmu.muhelp.model.XMPPConfiguration;
import za.ac.nmmu.muhelp.data.XMPPConfigurationRepository;

import za.ac.nmmu.muhelp.comms.Connection;
import za.ac.nmmu.muhelp.comms.XMPPListenerThread;

@Startup
@Singleton
public class Init {


    @Inject
    private Logger log;


    @Inject
    private XMPPConfigurationRepository xmppConfigurationRepository;

    @Inject
    Map<String, Connection> connections;


public void makeConnections() {
	log.info("=============== Make Connection Asynchronously=============");
	try {
		//
		// get all XMPP Configurations off data base and iterate
		//
		List<XMPPConfiguration> list = xmppConfigurationRepository.findAllLive();
		ListIterator<XMPPConfiguration> iterator = list.listIterator();
		while ( iterator.hasNext() ) {
			XMPPConfiguration xmppConfiguration = iterator.next();
			log.info(xmppConfiguration.getName() + " " + 
				xmppConfiguration.getUsername());

			if ( xmppConfiguration.getPassword().trim().equals("") ) {
				log.info("no password available");
				continue;
			}

			try {
				//
				/// create a connection configuration
				//
				ConnectionConfiguration connectionConfiguration = new
					ConnectionConfiguration(xmppConfiguration.getHost(), 
						xmppConfiguration.getPort(),
						xmppConfiguration.getName());
				log.info("creating connection");

				//
				// create an XMPP connection
				//
				XMPPConnection xmppConnection = new XMPPConnection(connectionConfiguration);

				//
				// create a muHelp Connection and store the XMPP Connection inside
				//
				Connection connection = new Connection();
				connection.setXMPPConnection(xmppConnection);
				connections.put(xmppConfiguration.getUsername(), connection);

				log.info("connections now has " + connections.size());
				log.info("connecting");
				xmppConnection.connect();
				log.info("logging in");

				//
				// login
				//
				xmppConnection.login(xmppConfiguration.getUsername(), xmppConfiguration.getPassword());
				log.info("logged in");
				log.info("chat manager is " + xmppConnection.getChatManager());

				//
				// start the thread
				//
    				XMPPListenerThread listener = new XMPPListenerThread();
				xmppConnection.getChatManager().addChatListener(listener);
				connection.setXMPPListenerThread(listener);
				log.info("chat listener added");
	
				Presence presence = new Presence(Presence.Type.available);
				presence.setStatus("Hey, I'm online.");
				xmppConnection.sendPacket(presence);
			}
			catch ( Throwable t ) {
				log.info("problems logging in");	
			}
			
		}
	}
	catch ( Throwable t ) {
		log.info("Sleep throwing " + t);
	}
	log.info("=============== Made Connection Asynchronously=============");

}

public void breakConnections() {
	log.info("Break Connections");

	try {
		Iterator<Connection> iterator = connections.values().iterator();;
		while ( iterator.hasNext() ) {
			Connection connection = iterator.next();
			log.info("need to remove listerner from " + connection);
			connection.getXMPPConnection().getChatManager().removeChatListener(connection.getXMPPListenerThread());
			log.info("and disconnect");
			connection.getXMPPConnection().disconnect(new Presence(Presence.Type.unavailable));
			log.info("stop thread");
			connection.stopThread();
		}
	}
	catch ( Throwable t ) {
		log.info("breakConnections throwing " + t);
	}

}

@PostConstruct
void postConstruct() {
	makeConnections();
	log.info("===============INIT==============");
	log.info("===============INIT==============");
	log.info("===============INIT==============");
	log.info("===============INIT==============");

}

@PreDestroy
void preDestroy() {
	breakConnections();
	log.info("=======DESTROYING=========");
	log.info("=======DESTROYING=========");
	log.info("=======DESTROYING=========");
}


}
